/*
 * Course:        COMP 380
 * Semester:      Summer 2012
 * Assignment:    Text To Speech
 * File Name:     PlayAudio.java
 * Author:        James Paul Pan
 * 				  Kenneth Wakeland
 * 				  Peter Xaymountry
 * Group #:		  Group #3
 */

package com.comp380.texttospeech;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
//import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;

/*
 * This class purpose allow the user to play, pause or 
 * stop the audio file they selected.
 */
public class PlayAudio extends Activity
{
        // Initialize the button variables.
        Button btnPlay, btnPause, 
                   btnReturn, btnStop;
        
        // Initialize the seekbar variable
        SeekBar progressBar;

	
        // Initialize the mediaplayer variable and set it to null.
        MediaPlayer mp = null;
        
        // Initialize the filePath string variable and set it to null.
        private String filePath = null;
        
        // Initialize this boolean variable and set it to false by default.
        private boolean progress_tracking_touch = false;
       
        // Initialize this int variable and set it to 0.
        private int kill_mp_Thread = 0;
        
        // Initialize this variable that keep track on the pause count.
        // Set to 0 by default.
        int countPause = 0;
        
        // Initialize this variable that keep track on the play count.
        // Set to 0 by default.
        int countPlay = 0;

        @Override    
        public void onCreate(Bundle savedInstanceState) 
        {
            //Keep the screen orientation in portrait mode
            super.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            
            // TODO Auto-generated method stub
            super.onCreate(savedInstanceState);

            // Set the layout to this activity.
            setContentView(R.layout.mediaplay);
            
            // Use Bundle to receive the data being pass from the SavedAudio class.
            Bundle params = getIntent().getExtras();
            
            // Pass the incoming data to be stored in the filePath string.
            filePath = params.getString("File");
            
            // Print out a message that display the file path.
            System.out.println(filePath);
            
            // Pass the variable to correspond with the TextView.
            TextView textView1 = (TextView) findViewById(R.id.textView1);

            // Display the location of the file being played.
            textView1.setText(filePath);

            // Pass the variable to correspond with the Play button.
            btnPlay = (Button) findViewById(R.id.buttonPlay);
           
            // This will handle what happen when the user click on the play button.
            btnPlay.setOnClickListener(new OnClickListener()
            {
            	/*
 				 * This method will handle what happen when the user click 
				 * on the Play button.
            	 *
            	 * @param v
            	 * 	This variable is just a default variable because this method
            	 *  require a parameter.
            	 */
                public void onClick(View v)
                {	
                	// If the pause button haven't been press, play the audio track.
                    if(countPause == 0)
                    {	
                        // Play the audio file.
                        mp_play();
                        
                        // Set the play count to 1.
                        countPlay = 1;
                    }
                    
                    // If the pause button been press, resume the audio track.
                    else if(countPause == 1)
                    {
                    	// Play the audio track.
                        mp_play();
                        
                        // Display a message that tell the user, the user press play again to resume
                        // the playing audio.
                        Toast.makeText(getBaseContext(), "Resume playing", Toast.LENGTH_SHORT).show();
                        
                        // Set the pause count back to 0.
                        countPause = 0;
                    }
                }
            });

            // Pass the variable to correspond with the Pause button.
            btnPause = (Button) findViewById(R.id.buttonPause);
            
            // When the button is click it goes to the onClick method and pause
    		// the audio track.
            btnPause.setOnClickListener(new OnClickListener()
            {
            	/*
				 * This method will handle what happen when the user click 
				 * on the Pause button.
            	 *
 				 * @param v
            	 * 	This variable is just a default variable because this method
            	 *  require a parameter.
            	 */
                public void onClick(View v)
                {
                	// If the Play button been press, it will pause the audio track.
                    if(countPlay == 1)
                    {
                    	// Display a message that tell the user, they press pause.
                        Toast.makeText(getBaseContext(), "Pause", Toast.LENGTH_SHORT).show();
                        
                        // Pause the audio track.
                        mp_pause();
                        
                        // Set the pause count to 1.
                        countPause = 1;
                    }
                    
                    // If the play button haven't been press, it will display a 
                    // message that the user have to play the audio track first.
                    else if(countPlay == 0)
                    {
                    	// Display a message that tell the user to play the audio track first.
                        Toast.makeText(getBaseContext(), "You have to play a audio first before you can pause it", Toast.LENGTH_SHORT).show();
                    }
                }
            });

            // Pass the variable to correspond with the Stop button.
            btnStop = (Button) findViewById(R.id.buttonStop);
            
            // When the button is click it goes to the onClick method and stop
    		// the audio track.
            btnStop.setOnClickListener(new OnClickListener()
            {
            	/*
				 * This method will handle what happen when the user click 
				 * on the Stop button.
            	 *
 				 * @param v
            	 * 	This variable is just a default variable because this method
            	 *  require a parameter.
            	 */
                public void onClick(View v)
                {
                	// If the play button been press, it will stop the audio track.
                    if(countPlay == 1)
                    {
                    	// Display a message that tell the user, they press stop.
                        Toast.makeText(getBaseContext(), "Stop", Toast.LENGTH_SHORT).show();
                        
                        // Stop the audio track.
                        mp_stop();
                    }
                    
                    // If the play button haven't been press, it will display a
                    // message that the user have to play the audio track first.
                    else if(countPlay == 0)
                    {
                        Toast.makeText(getBaseContext(), "You have to play a audio first before you can stop it", Toast.LENGTH_SHORT).show();
                    }
                }
            });

            // Pass the variable to correspond with the Return button.
            btnReturn = (Button) findViewById(R.id.buttonReturn);
            
            // When the button is click it goes to the onClick method and return the
            // user to the SavedAudio class.
            btnReturn.setOnClickListener(new OnClickListener()
            {
                public void onClick(View v)
                {
                		// Display a message that tell the user, they press return.
                        Toast.makeText(getBaseContext(), "Return", Toast.LENGTH_SHORT).show();
                        
                        // This will stop the playing audio, just if the user didn't press stop.
                        mp_stop();
                        
                        // This method is part of the Activity package and you call this
                        // when the main activity is done and should be close.
                        finish();
                        
                        // This variable will store the function that will 
            			// take the user to the SavedAudio screen.
                        Intent intent = new Intent(getBaseContext(), SavedAudio.class);
                        
                     // This will start the transition to select SavedAudio screen.
                        startActivity(intent);
                }
            });

            // Pass the variables to correspond with the seekBar.
            progressBar = (SeekBar)findViewById(R.id.seekBar1);
            
            // When the seekBar been adjusted it goes to the myOnSeekbarChangeListener 
            // method and adjust the audio track to the properly duration to start playing from.
            progressBar.setOnSeekBarChangeListener(new myOnSeekBarChangeListener());
            
            // This prepare the audio track by setting the file path and checking if the
            // audio track can be played or not.
            mp_prepare();
        }

        /*
         * This method will handle if the audio track can be played or not. If the audio track
         * cannot be play, it will display a message but if the audio track can be play it will
         * set the audio track file path and set the seekBar.
         */
        public void mp_prepare()
        {
        	// If the file path of the audio track is null, it will display a message that this program 
        	// cannot play the audio file.

            if(filePath == null)
            {
            	// Display a message that tell the user, the audio track cannot be played.
                Toast.makeText(getBaseContext(), "Sorry! Can't play file", Toast.LENGTH_SHORT).show();
                return ;
            }

            try
            {
            	// Set the kill thread to 0.
                kill_mp_Thread = 0;

                // Create a new mediaplayer object.
                mp = new MediaPlayer();

                // Set the path of the audio track to play.
                mp.setDataSource(filePath);
                
                
                mp.setAudioStreamType(AudioManager.STREAM_RING);
                
                // This will check if the audio track is completed.
                mp.setOnCompletionListener(new OnCompletionListener()
                {
                	/*
                	 * This method handle what to do when the audio track complete.
                	 * 
                	 * @param mp
                	 * 	The mediaplayer that will be check.
                	 */
                	public void onCompletion(MediaPlayer mp) 
                	{
                        // set the progress at the end
                        progressBar.setProgress(mp.getDuration());
                    }
                });
            
                
            mp.setOnPreparedListener(new OnPreparedListener() 
            {
                public void onPrepared(final MediaPlayer mp) 
                {
                    if(mp != null)
                    {
                    	progressBar.setMax(mp.getDuration());
                    }

                    new Thread(new Runnable() 
                    {
                           // @Override
                            public void run()
                            {
                                while(mp != null && kill_mp_Thread == 0 )
                                {
                                    try 
                                    {
                                    	Message msg = new Message();
                                        msg.what = mp.getCurrentPosition();;
                                        threadHandler.sendMessage(msg);

                                        Thread.sleep(100);
                                    } 
                                    
                                    catch (InterruptedException e) 
                                    {
                                    	return;
                                    } 
                                    
                                    catch (Exception e) 
                                    {
                                    	return;
                                    }
                                }

                                // confirm the Thread is stopped
                                kill_mp_Thread = 2;
                       }
                    }).start();
                }
            });

                // Prepare the object.
                mp.prepare();
            }
            
            catch (Exception e) 
            {
            	Toast.makeText(getBaseContext(), "Sorry! Can't play file", Toast.LENGTH_SHORT).show();
                e.printStackTrace();
            }
        }
        
        /*
         * This method will play the audio track.
         */
        public void mp_play()
        {	
            if(mp == null)
            {
               mp_prepare();
            }

            if(mp == null)
            {
                    Toast.makeText(getBaseContext(), "Not Playing", Toast.LENGTH_SHORT).show();
            }
            
            else
            {
            	// This check if the audio track is playing. If it is already playing,
            	// it will pause, reset the audio track to 0 and play the audio.
                if(mp.isPlaying())
                {
                	// This pause the audio track so it won't crash the program.
                	mp_pause();
                    
                	// This set the audio track to the beginning/
                	mp_seekTo(0);
                }
                	
                	// This will start playing the audio track.
                    mp.start();

                    // Display a message that tell the user, the user press play.
                    Toast.makeText(getBaseContext(), "Play", Toast.LENGTH_SHORT).show();
            }
        }

        /*
         * This method will stop the audio track playing.
         */
        public void mp_stop()  
        {
            // This variable will tell the thread to stop.
            kill_mp_Thread = 1;
            
            // This check if the audio track is not null. If it not 
            // null it will stop the audio track.
            if(mp != null)
            {
                //for the Thread to catch up if sleep
                for (int i = 0; i < 3 && kill_mp_Thread == 1;i++) 
                {
                    //Pause for 100 milli seconds
                    try 
                    {
                        Thread.sleep(100);
                    } 
                    
                    catch (InterruptedException e) 
                    {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                
                // This stop the audio track from playing.
                mp.stop();
                
                // This reset the audio track to null.
                mp = null;
                
                // This reset the seekBar to 0.
                progressBar.setProgress(0);
            }	
        }

        /*
         * This method will pause the audio track.
         */
        public void mp_pause()
        {	
        	// If the audio track is not null, it will get pause.
        	if(mp != null)
            {
        		// This will pause the audio track.
        		mp.pause();
            }
        }
        
        /*
         * This method will set the seekbar to the audio track.
         * 
         * @param seek
         * 	This will handle the duration of the song.
         */
        public void mp_seekTo(int seek)
        {
        	// If the audio track is not null, the duration of the
        	// audio track will get adjusted.
            if(mp != null)
            {
            	// This will pass the seekBar duration to the audio track duration.
                mp.seekTo(seek);
            }
        }
        
        /*
         * This class purpose is to listen to the seekBar being adjusted and playing
         * the audio track at the right duration.
         */
        public  class myOnSeekBarChangeListener implements OnSeekBarChangeListener
        {
            public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) 
            {
                if(fromUser)
                {
                    //System.out.println("progress user :"+progress);
                    mp_seekTo(progress);

                }
                
                else
                {
                }
            }

            public void onStartTrackingTouch(SeekBar seekBar) 
            {
                    progress_tracking_touch = true;
            }

            public void onStopTrackingTouch(SeekBar seekBar) 
            {
                    progress_tracking_touch = false;
            }

        }

        private Handler threadHandler = new Handler()
        {
            public void handleMessage(Message msg)
            {
                // do not update the progress if  the mp is not playing
                if(mp != null && mp.isPlaying() && !progress_tracking_touch)
                {
                        progressBar.setProgress(msg.what);
                }
            }
        };
}